package com.bea.ftd.routing.filter;

import com.bea.ftd.common.dao.ApiDefineRepo;
import com.bea.ftd.common.dao.PartnerInfoRepo;
import com.bea.ftd.common.entity.ApiDefine;
import com.bea.ftd.common.entity.PartnerInfo;
import com.bea.ftd.common.model.MappingResponse;
import com.bea.ftd.common.model.MappingRequest;
import com.bea.ftd.routing.feign.MappingFeign;
import com.google.gson.Gson;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StreamUtils;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;

import static com.netflix.zuul.context.RequestContext.getCurrentContext;

/**
 * 报文解析过滤器
 * */
public class MsgInputFilter extends AbstractZuulFilter {

    @Autowired
    ApiDefineRepo apiDefineRepo;

    @Autowired
    PartnerInfoRepo partnerInfoRepo;

    @Resource
    MappingFeign mappingFeign;

    private String apiId;
    private String partnerCode;
    private PartnerInfo partnerInfo;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext context = getCurrentContext();
        String url = context.getRequest().getRequestURI();
        List<ApiDefine> apiDefineList = apiDefineRepo.findByEnabled(1);
        for(int i=0;i<apiDefineList.size();i++){
            String pattern_url = apiDefineList.get(i).getPath();
            if((pattern_url.endsWith("**")&&url.contains(pattern_url.substring(0,pattern_url.length()-2)))
                    ||(pattern_url.endsWith("*")&&url.contains(pattern_url.substring(0,pattern_url.length()-1)))){
                this.partnerCode = apiDefineList.get(i).getParnterCode();
                this.partnerInfo =  partnerInfoRepo.findByPartnerCode(partnerCode);
                this.apiId = apiDefineList.get(i).getId();
                return true;
            }else{
                continue;
            }

        }
        return false;

    }


    @Override
    public Object run() {
        RequestContext context = getCurrentContext();
        try{
            logger.info("===========>开始报文解析");


            InputStream stream = context.getRequest().getInputStream();
            String body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
            logger.info(body);
            MappingRequest mappingRequest = new MappingRequest();
            mappingRequest.setPartnerCode(this.partnerCode);
            mappingRequest.setData(body);
            mappingRequest.setApiId(this.apiId);
            mappingRequest.setMsgInType(partnerInfo.getMsgInType());

            MappingResponse mappingResponse = mappingFeign.checkMsgInData(mappingRequest);
            if(mappingResponse.getErrorCode()==0){
                final byte[] reqBodyBytes = new Gson().toJson(mappingResponse.getDate()).getBytes("utf-8");
                context.set("apiId",this.apiId);
                context.set("msgInType",partnerInfo.getMsgInType());
                context.set("msgOutType",partnerInfo.getMsgOutType());
                context.set("partnerCode",partnerInfo.getPartnerCode());
                context.set("isSuccess", true);
                context.setRequest(new HttpServletRequestWrapper(getCurrentContext().getRequest()) {
                    @Override
                    public ServletInputStream getInputStream() throws IOException {
                        return new ServletInputStreamWrapper(reqBodyBytes);
                    }

                    @Override
                    public int getContentLength() {
                        return reqBodyBytes.length;
                    }

                    @Override
                    public long getContentLengthLong() {
                        return reqBodyBytes.length;
                    }
                });

            }else if(mappingResponse.getErrorCode()==9){
                context.set("apiId",this.apiId);
                context.set("needMapping",false);
            }else{
                context.setSendZuulResponse(false); //不对其进行路由
                context.setResponseStatusCode(400);
                context.getResponse().setCharacterEncoding("utf-8");
                context.setResponseBody("MsgInputFilter reject body checkType:\n"+mappingResponse.getErrorMsg());
                context.set("isSuccess", false);
            }
        }catch (Exception e){
            e.printStackTrace();
            context.setSendZuulResponse(false); //不对其进行路由
            context.getResponse().setCharacterEncoding("utf-8");
            context.setResponseStatusCode(400);
            context.setResponseBody("MsgInputFilter reject body checkType:\n"+e.getMessage());
            context.set("isSuccess", false);
        }
        return null;
    }
}
